<?php

class FileUploadController extends Controller
{
	/**
	 * @return array action filters
	 */
	public function filters()
	{
		return array(
			'accessControl', // perform access control for CRUD operations
		);
	}

	/**
	 * Specifies the access control rules.
	 * This method is used by the 'accessControl' filter.
	 * @return array access control rules
	 */
	public function accessRules()
	{
		return array(
			array('allow',
				'actions'=>array('index','ckeditor'),
				'users'=>array('@'),
			),
			array('deny',  // deny all users
				'users'=>array('*'),
			),
		);
	}

	public function actionIndex()
	{
            $uploadDirectory = $_SERVER['DOCUMENT_ROOT'].Yii::app()->request->baseUrl.'/upload/';
            $allowedExtensions = array('jpg', 'jpeg', 'png', 'gif', 'zip', 'rar', 'doc', 'docx'); 
            $result = array('success' => false, 'error' => 'Server error!!  Please contact the administrator.');

            if ($this->checkServerSettingsForPhotoUpload($uploadDirectory))
            {
                if (isset($_GET['qqfile']))
                {
                    $filenameParts = explode('.', $_GET['qqfile']); 

                    if (count($filenameParts) == 2)
                    {
                        if (in_array(strtolower($filenameParts[1]), $allowedExtensions))
                        {
                            $inputStream = fopen("php://input", "r"); 
                            $tempFile = tmpfile(); 
                            $tempFileSize = stream_copy_to_stream($inputStream, $tempFile);
                            fclose($inputStream);

                            if ($tempFileSize <= $this->toBytes(ini_get('post_max_size')) && $tempFileSize <= $this->toBytes(ini_get('upload_max_filesize'))
                                && $this->isWithinSizeLimit($tempFileSize))
                            {
                                $filename = time().'.'.$filenameParts[1];
                                $target = fopen($uploadDirectory.$filename, "w");
                                fseek($tempFile, 0, SEEK_SET);
                                stream_copy_to_stream($tempFile, $target);
                                fclose($target);
                                
                                $result = array('success' => true, 'imgurl' => Yii::app()->request->baseUrl.'/upload/'.$filename);
                            }
                            else
                            {
                                if (isset($_GET['sizeLimit']))
                                {
                                    $result = array('success' => false, 'error' => Yii::t('core_msg', 'Uploaded file size cannot exceed').$_GET['sizeLimit'].'。');
                                }
                                else
                                {
                                    $result = array('success' => false, 'error' => Yii::t('core_msg', 'File size exceed upload limit.'));
                                }
                            }
                        }
                    }
                }
                else if (isset($_FILES['qqfile']))
                {
                    $filenameParts = explode('.', $_FILES['qqfile']['name']);

                    if (count($filenameParts) == 2)
                    {
                        if (in_array(strtolower($filenameParts[1]), $allowedExtensions))
                        {
                            if ($_FILES['qqfile']['size'] <= $this->toBytes(ini_get('post_max_size')) 
                                && $_FILES['qqfile']['size'] <= $this->toBytes(ini_get('upload_max_filesize'))
                                && $this->isWithinSizeLimit($_FILES['qqfile']['size']))
                            {
                                $filename = time().'.'.$filenameParts[1];

                                if (move_uploaded_file($_FILES['qqfile']['tmp_name'], $uploadDirectory.$filename))
                                {
                                    $result = array('success' => true, 'imgurl' => Yii::app()->request->baseUrl.'/upload/'.$filename);
                                }
                            }
                            else
                            {
                                if (isset($_GET['sizeLimit']))
                                {
                                    $result = array('success' => false, 'error' => Yii::t('core_msg', 'Uploaded file size cannot exceed').$_GET['sizeLimit'].'。');
                                }
                                else
                                {
                                    $result = array('success' => false, 'error' => Yii::t('core_msg', 'File size exceed upload limit.'));
                                }
                            }
                        }
                    }
                } 
            }

            echo json_encode($result);
            Yii::app()->end();
	}

        public function actionCkeditor()
        {
            $uploadDirectory = $_SERVER['DOCUMENT_ROOT'].Yii::app()->request->baseUrl.'/upload/';
            $allowedExtensions = array('jpg', 'jpeg', 'png', 'gif'); 
            $result = 'Server error!!  Please contact the administrator.';
            $funcNum = $_GET['CKEditorFuncNum'];
            $url = '';

            if ($this->checkServerSettingsForPhotoUpload($uploadDirectory))
            {
                if (isset($_FILES['upload']))
                {
                    $filenameParts = explode('.', $_FILES['upload']['name']);

                    if (count($filenameParts) == 2)
                    {
                        if (in_array(strtolower($filenameParts[1]), $allowedExtensions))
                        {
                            if ($_FILES['upload']['size'] <= $this->toBytes(ini_get('post_max_size')) 
                                && $_FILES['upload']['size'] <= $this->toBytes(ini_get('upload_max_filesize')))
                            {
                                $filename = time().'.'.$filenameParts[1];

                                if (move_uploaded_file($_FILES['upload']['tmp_name'], $uploadDirectory.$filename))
                                {
                                    $url = Yii::app()->request->baseUrl.'/upload/'.$filename;
                                    $result = Yii::t('core_msg', 'File has been successfully uploaded.');
                                }
                            }
                            else
                            {
                                $result = 'The uploaded file size exceed server limitation!!  Please contact the administrator.'; 
                            }   
                        }
                    }
                }
            }

            echo "<script type='text/javascript'>window.parent.CKEDITOR.tools.callFunction($funcNum, '$url', '$result');</script>";
            Yii::app()->end();
        }

        protected function checkServerSettingsForPhotoUpload($uploadDirectory)
        {
            $result = TRUE;

            if (!empty($uploadDirectory))
            {
                if (!is_writable($uploadDirectory)) 
                {
                    Yii::log($uploadDirectory.' is not writable.', 'error');
                    $result = FALSE;
                }
            }
            else
            {
                $result = FALSE;
            }

            return $result;
        }


	protected function toBytes($phpSizeStr)
	{
            $val = 0;

            if (!empty($phpSizeStr))
            {
                $sizeStr = trim($phpSizeStr);
                $lastChar = substr($sizeStr, -1);
                $sizeStr = trim(str_replace($lastChar, '', $sizeStr));

                if (is_numeric($sizeStr))
                {
                    switch(strtolower($lastChar))
                    {
                        case 'g':
                            $val = intval($sizeStr) * 1024 * 1024 * 1024;
                            break;
                        case 'm':
                            $val = intval($sizeStr) * 1024 * 1024;
                            break;
                        case 'k':
                            $val = intval($sizeStr) * 1024;
                            break;
                    }
                }
            }

            return $val;
	}

        protected function isWithinSizeLimit($fileSize)
        {
            $result = FALSE;

            // If size limit is set.
            if (isset($_GET['sizeLimit']))
            {
                $sizeLimit = $this->toBytes($_GET['sizeLimit']);

                if ($sizeLimit > 0 && $fileSize <= $sizeLimit)
                {
                    $result = TRUE;
                }
            }
            else
            {
                $result = TRUE;
            }

            return $result;
        }
}
